package algo;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import sudoku.SudokuEinzelfeld;

public class SetGenerator {

	public Set<Set<Integer>> getSets(int length, List<SudokuEinzelfeld> struct) {
		if (length == 2) {
			return get2erSets(struct);
		}
		return null;

	}

	private Set<Set<Integer>> get2erSets(List<SudokuEinzelfeld> struct) {
		Set<Integer> lookForNumbers = analyseStruct(struct);
		System.out.println("Found following numbers: " + lookForNumbers);
		Set<Set<Integer>> sets = buildSubSetsFromOneSet(lookForNumbers, 2);
		Iterator<Set<Integer>> setIter = sets.iterator();
		while(setIter.hasNext()){
			Set<Integer> singleSet = setIter.next();
			if(singleSet.size() != 2){
				setIter.remove();
			}
		}
		return sets;
	}
	
	private Set<Set<Integer>> buildSubSetsFromOneSet(Set<Integer> singleSet, int size) {
		Set<Set<Integer>> singlesubsets = new HashSet<Set<Integer>>();
		if(singleSet.size() == 1 || singleSet.isEmpty()){
			singlesubsets.add(new HashSet<Integer>());
			return singlesubsets;
		}
		List<Integer> tmp = new ArrayList<Integer>(singleSet);
		Integer head = tmp.get(0);
		Set<Integer> rest = new HashSet<Integer>(tmp.subList(1, tmp.size()));
		for (Set<Integer> set:buildSubSetsFromOneSet(rest, size)) {
			Set<Integer> newSet = new HashSet<Integer>();
			newSet.add(head);
			newSet.addAll(set);
			singlesubsets.add(newSet);
			singlesubsets.add(set);
		}
		return singlesubsets;
	}

	private List<Integer[]> getSetPairs(Integer integer, Set<Integer> restNr,
			List<SudokuEinzelfeld> struct) {
		for (SudokuEinzelfeld sudokuEinzelfeld : struct) {
			for (Integer integ : restNr) {
				
			}
		}
		return null;
	}

	private Set<Integer> analyseStruct(List<SudokuEinzelfeld> struct) {
		Set<Integer> numbers = new HashSet<Integer>();
		for (SudokuEinzelfeld sudokuEinzelfeld : struct) {
			if (sudokuEinzelfeld.getNumber() == 0) {
				Set<Integer> possNr = sudokuEinzelfeld.getPossibleNumbers();
				numbers.addAll(possNr);
			}
		}

		return numbers;
	}

}
